import time, glob, os
import cherrypy
from cherrypy.lib.static import serve_file
import atlas
from atlas import util, web, sql
from atlas.web import formlib
from mako import exceptions
from mako.template import Template
from mako.lookup import TemplateLookup

class Root(object):
    """
    Base Class for all web related classes
    """

    def page(self, name, **kwds):
        "Fills a template"
        templ = self.lookup.get_template( name )
        try:
            return  templ.render( **kwds )
        except:
            return exceptions.html_error_template().render()
    
    def set_conf(self, conf):
        "Sets internal parameters"
        self.conf = conf
        self.lookup = TemplateLookup(directories=[ conf.TEMPLATE_DIR ], module_directory=conf.SESSION_DIR)

class WebRoot(Root):
   
    @cherrypy.expose
    def download(self, filename=''):
        """
        Generates directory listing for the files in the export folder
        """
        files = map( os.path.basename, glob.glob( self.conf.DOWNLOAD_DIR + "/*" ) )
        '''
        if filename:
            assert filename in files, 'Requested file has not been found'
            fullpath = atlas.join_paths( self.conf.DOWNLOAD_DIR, filename )
            content_type='application/octet'
            return serve_file( fullpath,content_type='application/octet' )
        '''
        param = atlas.Param( files=files )
        return self.page('download.html', param=param )

    @cherrypy.expose
    def search(self, word='', submit=''):
        """
        Default search page
        """
        
        param = atlas.Param( word=word )
        # search with features based on param.feature
        
        # search for a given 
        session = sql.get_session( self.conf.SQL_URI )

        if param.word:
            def search_query( word, text ):
                query = session.query(sql.Feature).filter( "name LIKE :word or altname LIKE :text" ).params(word=word, text=text)
                query = list(query[:20])
                return query

            # a little heuristics to match most likely target
            targets = [ 
                (param.word+'%', 'No match'), # match beginning
                ('%'+param.word+'%', 'No match'), # match name anywhere
                ('%'+param.word+'%', '%'+param.word+'%'), # match json anywhere
            ]
            for word, text in targets:
                query = search_query( word=word, text=text)
                if query:
                    break
        else:
            query = []

        return self.page('search.html', param=param, query=query)

    @cherrypy.expose
    def index(self, **kwds):
        """
        Main request handler
        """
       
        # the main configuration file
        conf = self.conf

        # generate a new form based on the configuration
        form = formlib.main_form( conf )
        
        # clear the tempdir every once in a while
        util.clear_tempdir( dir=conf.IMAGE_DIR, days=1, chance=10)

        incoming = form.defaults()
        incoming.update( kwds )
        
        # manage the zoom and pan requests
        incoming = formlib.zoom_change( kdict=incoming, levels=conf.LEVELS)
        incoming = formlib.pan_view( kdict=incoming )
        
        # process the form
        param = atlas.Param( **incoming )
        form.process( incoming )

        if kwds and form.isSuccessful():
            # adds the sucessfull parameters
            param.update( form.values() )

        # if it was a search word not a number go to search page
        try:
            center = int( param.feature )
        except ValueError:
            # go and search for these
            raise cherrypy.HTTPRedirect('/search?word=%s' % param.feature)

        # keep image at a sane size
        param.width  = min( [2000, int(param.img_size)] )
        
        # get the template and the function used to generate the tracks
        tmpl_name, track_maker  = conf.PLOT_MAPPER[param.plot]
        
        if track_maker is not None:
            # generate the name that the image will be stored at
            fname, fpath = util.make_tempfile( dir=conf.IMAGE_DIR, suffix='.png')
            param.fname  = fname

            # generate the track
            track_chart = track_maker( param=param, conf=conf )
            track_chart.save(fname=fpath)
        
        return self.page(tmpl_name, conf=conf, form=form, param=param)

def test( verbose=0 ):
    "Performs module level testing"
    import doctest
    doctest.testmod( optionflags=doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE, verbose=verbose )

if __name__ == "__main__":
    test()


